package cn.kent.base.deadLock;

/**
 * 创建死锁：
 * 让线程A先持有资源A，开始休眠1s然后在资源A中再申请资源B
 * 让线程B先持有资源B，开始休眠1s然后在资源B中再申请资源A
 * <p>
 * 满足死锁四大条件：互斥，请求并持有，环路等待，不可剥夺
 * <p>
 * 破坏死锁四大条件就会避免死锁：
 * 将threadB改成和threadA一样的代码，就会A使用完resourceA，B继续使用resourceA，就不会造成死锁了。 —— 本质是让资源具有有序性，即：必须先申请到资源A才能申请资源B，那么久破坏了环路等待
 */
public class DeadLockTest2 {
    private static Object resourceA = new Object();
    private static Object resourceB = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (resourceA) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread() + " 已经持有资源A开始申请资源B");
                    synchronized (resourceB) {
                        System.out.println(Thread.currentThread() + " 持有资源B");
                    }
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (resourceB) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread() + " 已经持有资源B开始申请资源A");
                    synchronized (resourceA) {
                        System.out.println(Thread.currentThread() + " 持有资源A");
                    }
                }
            }
        });

        threadA.start();
        threadB.start();
        threadA.join();
        threadB.join();
        System.out.println("main thread is over");

    }
}
